package net.htjs.juc.deadlock.v1;

import lombok.extern.slf4j.Slf4j;

/**
 * 哲学家就餐问题
 */
@Slf4j
public class PhilosopherDinner {

    public static void main(String[] args) {

        Chopstick c1 = new Chopstick("1");
        Chopstick c2 = new Chopstick("2");
        Chopstick c3 = new Chopstick("3");
        Chopstick c4 = new Chopstick("4");
        Chopstick c5 = new Chopstick("5");
        new Philosopher("苏格拉底", c1, c2).start();
        new Philosopher("柏拉图", c2, c3).start();
        new Philosopher("亚里士多德", c3, c4).start();
        new Philosopher("赫拉克利特", c4, c5).start();
        //死锁演示
        //new Philosopher("阿基米德", c5, c1).start();
        //线程饥饿
        new Philosopher("阿基米德", c1, c5).start();
    }

    /**
     * 哲学家类
     */
    @Slf4j
    static class Philosopher extends Thread{

        private Chopstick left;
        private Chopstick right;

        public Philosopher(String name, Chopstick left, Chopstick right) {
            super(name);
            this.left = left;
            this.right = right;
        }

        @Override
        public void run() {
            while (true) {
                synchronized (left) {
                    synchronized (right) {
                        log.info("哲学家 {} 开始吃", getName());
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }
    }

    static class Chopstick {
        private String name;

        public Chopstick(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return "Chopstick{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
}
